package com.glodon.paas.qto.dao.impl;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.glodon.paas.job.model.TaskStatus;
import com.glodon.paas.qto.dao.TaskRepositoryCustom;
import com.glodon.paas.qto.model.Task;
import com.glodon.paas.qto.model.TaskProgress;

public class TaskRepositoryImpl implements TaskRepositoryCustom {
    @Autowired(required = false)
    private MongoOperations mongoOperations;

    @Override
    public long getChildTaskCompleteCount(String parentId) {
        long count = mongoOperations.count(
                Query.query((Criteria.where("parentId").is(parentId).and("status").is(TaskStatus.success))), Task.class);
        return count;
    }

    /**
     * 更新虚拟父类.
     * 
     * @param taskId
     * @return 成功更新返回true，否则返回false，返回false是由于并发更新请求，只有一个能成功更新。
     */
    @Override
    public boolean modifyVirtualTask(String taskId) {
        Task task = mongoOperations.findAndModify(
                Query.query(Criteria.where("id").is(taskId).and("responseTime").is(null)),
                Update.update("responseTime", new Date()), Task.class);
        return task != null;
    }

    @Override
    public boolean modifyTaskProgress(String jobServerTaskId, TaskProgress progress) {
        Query query = null;
        TaskStatus status = progress.getStatus();
        if (status == null) {//未知状态
            return false;
        }
        if (TaskStatus.success.equals(status) || TaskStatus.failure.equals(status) || TaskStatus.canceled.equals(status)) {
            query = Query.query(Criteria.where("jobServerTaskId").is(jobServerTaskId));
        } else {
            query = Query.query(Criteria.where("jobServerTaskId").is(jobServerTaskId).and("progress")
                    .lt(progress.getProgress()));
        }
        Task task = mongoOperations.findAndModify(
                query,
                Update.update("responseTime", new Date()).set("progress", progress.getProgress())
                        .set("status", status)
                        .set("message", progress.getMessage())/*
                        .set("output", progress.getOutput())*/, Task.class);
        return task != null;
    }

    public void setMongoOperations(MongoOperations mongoOperations) {
        this.mongoOperations = mongoOperations;
    }
}
